package cn.caskm.souvenirshopsystem.service.impl;

import cn.caskm.souvenirshopsystem.constants.BizConstants;
import cn.caskm.souvenirshopsystem.domain.Result;
import cn.caskm.souvenirshopsystem.domain.dto.PageDTO;
import cn.caskm.souvenirshopsystem.domain.po.AdminUser;
import cn.caskm.souvenirshopsystem.domain.po.Announcement;
import cn.caskm.souvenirshopsystem.domain.query.AnnouncementQuery;
import cn.caskm.souvenirshopsystem.domain.vo.AnnouncementVO;
import cn.caskm.souvenirshopsystem.exceptions.BizException;
import cn.caskm.souvenirshopsystem.mapper.AnnouncementMapper;
import cn.caskm.souvenirshopsystem.service.AdminUserService;
import cn.caskm.souvenirshopsystem.service.AnnouncementService;
import cn.caskm.souvenirshopsystem.utils.UserContext;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Announcement> implements AnnouncementService {

    private final AdminUserService adminUserService;

    @Override
    public Result<PageDTO<AnnouncementVO>> page(AnnouncementQuery query) {
        // 获取参数
        Long pageNum = query.getPageNum();
        if (pageNum == null) {
            pageNum = BizConstants.DEFAULT_PAGE_NUM;
        }
        Long pageSize = query.getPageSize();
        if (pageSize == null) {
            pageSize = BizConstants.DEFAULT_PAGE_SIZE;
        }

        // 查询数据
        Page<Announcement> page = lambdaQuery()
                .like(StrUtil.isNotBlank(query.getTitle()), Announcement::getTitle, query.getTitle())
                .eq(StrUtil.isNotBlank(query.getAnnouncementType()), Announcement::getAnnouncementType, query.getAnnouncementType())
                .eq(StrUtil.isNotBlank(query.getStatus()), Announcement::getStatus, query.getStatus())
                .eq(StrUtil.isNotBlank(query.getIsTop()), Announcement::getIsTop, query.getIsTop())
                .orderByDesc(Announcement::getIsTop)
                .orderByDesc(Announcement::getPublishTime)
                .page(new Page<>(pageNum, pageSize));

        List<Announcement> announcements = page.getRecords();
        if (CollUtil.isEmpty(announcements)) {
            return Result.success(PageDTO.empty());
        }

        // 获取发布者信息
        Set<Long> publisherIds = announcements.stream().map(Announcement::getPublisherId).collect(Collectors.toSet());
        Map<Long, AdminUser> publisherMap = Collections.emptyMap();
        if (CollUtil.isNotEmpty(publisherIds)) {
            List<AdminUser> publishers = adminUserService.lambdaQuery()
                    .in(AdminUser::getId, publisherIds)
                    .list();
            if (CollUtil.isNotEmpty(publishers)) {
                publisherMap = publishers.stream().collect(Collectors.toMap(AdminUser::getId, p -> p));
            }
        }

        // 组装VO
        List<AnnouncementVO> result = new ArrayList<>(announcements.size());
        for (Announcement announcement : announcements) {
            AnnouncementVO vo = BeanUtil.copyProperties(announcement, AnnouncementVO.class);
            AdminUser publisher = publisherMap.get(announcement.getPublisherId());
            if (publisher != null) {
                vo.setPublisherName(publisher.getUserName());
            }
            result.add(vo);
        }

        return Result.success(PageDTO.of(result, page.getPages(), page.getTotal()));
    }

    @Override
    public Result<AnnouncementVO> detail(Integer announcementId) {
        Announcement announcement = getById(announcementId);
        if (announcement == null) {
            throw new BizException("公告不存在");
        }

        // 增加浏览次数
        announcement.setViewCount(announcement.getViewCount() == null ? 1 : announcement.getViewCount() + 1);
        updateById(announcement);

        // 获取发布者信息
        AdminUser publisher = adminUserService.getById(announcement.getPublisherId());
        
        AnnouncementVO vo = BeanUtil.copyProperties(announcement, AnnouncementVO.class);
        if (publisher != null) {
            vo.setPublisherName(publisher.getUserName());
        }

        return Result.success(vo);
    }

    @Override
    public Result<Void> publishAnnouncement(Announcement announcement) {
        Long userId = UserContext.getUser();
        if (userId == null) {
            throw new BizException("用户未登录");
        }

        announcement.setPublisherId(userId);
        announcement.setCreateTime(LocalDateTime.now());
        announcement.setUpdateTime(LocalDateTime.now());
        announcement.setPublishTime(LocalDateTime.now());
        announcement.setStatus("1"); // 已发布
        announcement.setViewCount(0);
        announcement.setIsTop("0"); // 默认不置顶

        save(announcement);
        return Result.success();
    }

    @Override
    public Result<Void> updateAnnouncement(Announcement announcement) {
        if (announcement.getAnnouncementId() == null) {
            throw new BizException("公告ID不能为空");
        }

        Announcement existing = getById(announcement.getAnnouncementId());
        if (existing == null) {
            throw new BizException("公告不存在");
        }

        announcement.setUpdateTime(LocalDateTime.now());
        updateById(announcement);
        return Result.success();
    }

    @Override
    public Result<Void> deleteAnnouncement(Integer announcementId) {
        Announcement announcement = getById(announcementId);
        if (announcement == null) {
            throw new BizException("公告不存在");
        }

        removeById(announcementId);
        return Result.success();
    }

    @Override
    public Result<Void> updateStatus(Integer announcementId, String status) {
        Announcement announcement = getById(announcementId);
        if (announcement == null) {
            throw new BizException("公告不存在");
        }

        announcement.setStatus(status);
        announcement.setUpdateTime(LocalDateTime.now());
        updateById(announcement);
        return Result.success();
    }

    @Override
    public Result<Void> updateTop(Integer announcementId, String isTop) {
        Announcement announcement = getById(announcementId);
        if (announcement == null) {
            throw new BizException("公告不存在");
        }

        announcement.setIsTop(isTop);
        announcement.setUpdateTime(LocalDateTime.now());
        updateById(announcement);
        return Result.success();
    }
}
